package com.wsx.ones.cloud.redis.impl;

import com.wsx.ones.cloud.redis.RedisService;
import com.wsx.ones.cloud.util.GsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by wangshuaixin on 17/5/11.
 */
@Service
public class RedisServiceImpl implements RedisService {

    @Autowired
    private RedisTemplate<String, ?> redisTemplate;

    @Override
    public boolean set(String key,int db, String value) {
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                redisConnection.select(db);
                redisConnection.set(serializer.serialize(key), serializer.serialize(value));
                return true;
            }
        });
        return result;
    }

    @Override
    public String get(String key,int db) {
        return redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                redisConnection.select(db);
                return serializer.deserialize(redisConnection.get(serializer.serialize(key)));
            }
        });
    }

    @Override
    public boolean expire(String key,int db, long expire) {
        return redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                redisConnection.select(db);
                return redisConnection.expire(serializer.serialize(key), expire);
            }
        });
    }

    @Override
    public <T> boolean setList(String key,int db, List<T> list) {
        return set(key, db, GsonUtil.getString(list));
    }

    @Override
    public <T> List<T> getList(String key,int db, Class<T> clz) {
        String json = get(key, db);
        if (null != json) {
            return GsonUtil.toList(json, clz);
        }
        return null;
    }

    @Override
    public long lpush(String key,int db, Object obj) {
        String value = GsonUtil.getString(obj);
        Long count = redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                redisConnection.select(db);
                return redisConnection.lPush(serializer.serialize(key), serializer.serialize(value));
            }
        });
        return count;
    }

    @Override
    public long rpush(String key,int db, Object obj) {
        String value = GsonUtil.getString(obj);
        Long count = redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                redisConnection.select(db);
                return redisConnection.rPush(serializer.serialize(key), serializer.serialize(value));
            }
        });
        return count;
    }

    @Override
    public String lpop(String key,int db) {
        return redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                redisConnection.select(db);
                return serializer.deserialize(redisConnection.lPop(serializer.serialize(key)));
            }
        });
    }
}
